package getui;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;



public class AllTest {
	// 读取excel
	private static int minpts = 4;
	private static double radius = 0.02;
	private static List<List<double[]>> clusters;
	private static List<double[]> cores;
	private static ArrayList<double[]> columnList = new ArrayList<double[]>();
	private static double[][] points = {};

	/**
	 * put the core point to cluster and get the densityconnect
	 * 
	 * @param points
	 * @param cores
	 */
	private static void putCoreToCluster(List<double[]> cores, double[][] points) {
		clusters = new ArrayList<List<double[]>>();
		int clusterNum = 0;
		for (int i = 0; i < cores.size(); i++) {
			clusters.add(new ArrayList<double[]>());
			clusters.get(clusterNum).add(cores.get(i));
			densityConnected(points, cores.get(i), clusterNum);
			clusterNum++;
		}
	}

	/**
	 * 
	 * @param points
	 * @param core
	 * @param clusterNum
	 */
	private static void densityConnected(double[][] points, double[] core, int clusterNum) {
		boolean isputToCluster;// 是否已经归为某个类
		boolean isneighbour = false;// 是不是core的“邻居”
		cores.remove(core);// 对某个core点处理后就从core集中去掉
		for (int i = 0; i < points.length; i++) {
			isneighbour = false;
			isputToCluster = false;
			for (List<double[]> cluster : clusters) {
				if (cluster.contains(points[i])) {// 如果已经归为某个类
					isputToCluster = true;
					break;
				}
			}
			if (isputToCluster)
				continue;// 已在聚类中，跳过，不处理
			if (countEurDistance(points[i], core) < radius) {// 是目前加入的core点的“邻居”吗？，ture的话，就和这个core加入一个类
				clusters.get(clusterNum).add(points[i]);
				isneighbour = true;
			}
			if (isneighbour) {// 如果是邻居，才会接下来对邻居进行densityConnected处理，否则，结束这个core点的处理
				if (cores.contains(points[i])) {
					cores.remove(points[i]);
					densityConnected(points, points[i], clusterNum);
				}
			}
		}

	}

	/**
	 * find the core points
	 * 
	 * @param points
	 * @param minpts
	 * @param radius
	 * @return
	 */
	private static List<double[]> findCores(double[][] points, int minpts, double radius) {
		List<double[]> cores = new ArrayList<double[]>();
		for (int i = 0; i < points.length; i++) {
			int pts = 0;
			for (int j = 0; j < points.length; j++) {
				if (countEurDistance(points[i], points[j]) < radius) {
					pts++;
				}
			}
			if (pts >= minpts) {
				cores.add(points[i]);
			}
		}
		return cores;
	}

	/**
	 * 欧氏距离
	 * 
	 * @param point1
	 * @param point2
	 * @return
	 */
	private static double countEurDistance(double[] point1, double[] point2) {
		double eurDistance = 0.0;
		for (int i = 0; i < point1.length; i++) {
			eurDistance += (point1[i] - point2[i]) * (point1[i] - point2[i]);
		}
		return Math.sqrt(eurDistance);
	}

	public static List<double[]> rout(String rount, List<double[]> columnList) {
		try {
			File file = new File(rount);
			FileInputStream in = new FileInputStream(file);
			XSSFWorkbook wb = new XSSFWorkbook(in);
			// 取得工作表
			Sheet sheet = wb.getSheetAt(0);
			int firstRowNum = sheet.getFirstRowNum();
			int lastRowNum = sheet.getLastRowNum();

			Row row = null;
			Cell cell_gid = null;
			Cell cell_day = null;
			Cell cell_lnglat = null;
			for (int i = firstRowNum; i <= lastRowNum; i++) {
				row = sheet.getRow(i); // 取得第i行
				cell_gid = row.getCell(0); // 取得i行的第一列
				cell_day = row.getCell(2);
				cell_lnglat = row.getCell(5);
				row.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
				if ("ANDROID-1317c262b0e84a87aac33b950087a4d7".equals(cell_gid.getStringCellValue())
						&& "201604".equals(cell_day.getStringCellValue().substring(0, 6))) {
					String[] lnglat = cell_lnglat.getStringCellValue().split(",");
					double lng = Double.parseDouble(lnglat[0]);
					double lat = Double.parseDouble(lnglat[1]);
					columnList.add(new double[] { lng, lat });
				}

			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return columnList;
	}

	public static void main(String[] args) {
		long starttime = System.currentTimeMillis();
		int a = 0;
		ArrayList<double[]> columnList = new ArrayList<double[]>();
		// 取出excel表中的数据
		List<double[]> aList = rout("C:/Users/Administrator/Desktop/geohash/xw_ndrc_staff_trail_one_five.xlsx", columnList);
		double[][] points = new double[aList.size()][2];
		Kmeans k = new Kmeans(1);
		ArrayList<ArrayList<float[]>> clusterdataSet = new ArrayList<>();

		for (int i = 0; i < aList.size(); i++) { // 如何double[] 转为double[][]
			for (int n = 0; n < 2; n++) {
				points[i][n] = aList.get(i)[n];
			}
		}
		System.out.println(points);
		// DBSCAN算法
		cores = findCores(points, minpts, radius);
		putCoreToCluster(cores, points);
		int i = 0;
		int j = 0;
		int n = 0;
		for (List<double[]> cluster : clusters) {
			System.out.println("cluster " + i++ + ":");
			ArrayList<float[]> dataSet = new ArrayList<float[]>();
			// ArrayList<float[]> dataSet = null;
			for (double[] point : cluster) {
				// System.out.println("[" + point[0] + "," + point[1] + "]");
				dataSet.add(new float[] { (float) point[0], (float) point[1] });

			}
			// 设置原始数据集
			k.setDataSet(dataSet);
			// 执行kmeans算法
			k.execute();
			// 得到中心结果
			ArrayList<float[]> initCenters = k.initCenters();
			Float[] f = new Float[initCenters.size()];
			// List<GeoHash> listGeo = new ArrayList<>();
			for (int i1 = 0; i1 < initCenters.size(); i1++) {
				System.out.println("jieguoji " + j++ + ":" + initCenters.get(i1)[0] + "," + initCenters.get(i1)[1]);
				// 输出geohash
				GeoHash geoHash = new GeoHash(initCenters.get(i1)[0], initCenters.get(i1)[1]);
				System.out.println("geoHash" + n++ + ":" + geoHash.getGeoHashBase32());
			}
			// 经纬度转换为geohash算法

		}
		// int flag = 0;
		// for (int j = 0; j < points.length; j++) {
		// flag = 0;
		// for (List<double[]> cluster : clusters) {
		// if (cluster.contains(points[j])) {
		// flag = 1;
		// break;
		// }
		// }
		// if (flag == 0)
		// System.out.println("noise point:" + "[" + points[j][0] + "," +
		// points[j][1] + "]");
		// }

		// cluster 12:

		System.out.println(System.currentTimeMillis() - starttime);
	}
}
